/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-04
 * V4.0
 */
package com.jphenix.kernel.objectloader.instanceb;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.jphenix.driver.log.systemouta.SystemOutLog;
import com.jphenix.driver.log.util.LogUtil;
import com.jphenix.driver.log.util.NullLogShadow;
import com.jphenix.driver.propertie.instanceb.XmlConfProp;
import com.jphenix.kernel.classloader.BeanClassLoader;
import com.jphenix.kernel.classloader.ResourceService;
import com.jphenix.kernel.classloader.ResourcesLoader;
import com.jphenix.kernel.objectloader.exception.BeanException;
import com.jphenix.kernel.objectloader.interfaceclass.IBean;
import com.jphenix.kernel.objectloader.interfaceclass.IBeanFactory;
import com.jphenix.kernel.objectloader.interfaceclass.IBeanFactoryManager;
import com.jphenix.kernel.objectloader.interfaceclass.IRemoteBeanFactory;
import com.jphenix.kernel.objectloader.util.ShadowBeanUtil;
import com.jphenix.kernel.objectloader.vo.BeanVO;
import com.jphenix.kernel.objectloader.vo.LoadBeanVO;
import com.jphenix.share.lang.SortVector;
import com.jphenix.share.util.BaseUtil;
import com.jphenix.share.util.ClassUtil;
import com.jphenix.share.util.DebugUtil;
import com.jphenix.share.util.SFilesUtil;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.log.ILog;
import com.jphenix.standard.log.ILogShadow;

/**
 * 类加载器
 * 
 *     类加载器编号为空时，父类加载器或者更上一级的类加载器中获取。
 *     如果获取类实例时指定类加载器编号则只能在父类加载器的一级子
 *     类加载器，或者父类的父类一级子类加载器中获取
 *     
 *                   
 *                                [04A BF]         [05A BF]
 *                               /                /
 *                        [03A BF]---------[04B BF]------[05B BF]-----[06A BF]
 *                        /      \                \             \
 *                       /        \[04C BF]        \[05C BF]     \[06B BF]
 *                      /                 \
 *                     /                   \[05D BF]
 *                    /
 *     [01 BF]---[02 BF]---[03B BF]---[04D BF]
 *                     \
 *                      \[03C BF]
 *                      
 *   例如： 06A BF类加载器中的类
 *   
 *         能获取到 06B,05A,05C,04A,04C,03B,03C 类加载器中的资源
 *         无法获取到 05D,04D 类加载器中的资源
 *                                         
 *  注意： 类加载器在启动时，先扫描jar包内部的受管控类，这个方案终止了，不可行
 *        在启动时遇到了锁死，也实在没必要做这个功能。
 *        
 *        当时发现脚本中调用脚本类中，有引用jar包内部类的，后来也通过直接引用类路径的方式解决了
 *        
 *   开发模式：
 *   
 *        1.日志模块只输出控制台，并不写入日志文件。
 *        2.脚本源文件夹中，支持 .disabled 文件，屏蔽指定文件夹（包括子文件夹）中的源文件。
 *          因为有些脚本只有在生产环境中连接生产库，或调用生产环境目标接口才起作用。在本地环境会报错。
 *          比如一些定时任务没必要在本地环境跑，即可屏蔽这些脚本。
 *        3.在自开发程序中，可以调用类加载器中方法判断是否为开发模式，针对不同模式做处理，比如选择性日志输出等。
 *        
 *   只有程序员在本机开发时，将本机环境设置为开发模式。切忌在测试环境和生产环境设置为开发模式。
 *   
 *   
 *   调试模式：拟废弃。从开发这个模式后，几乎从没用过这个模式。
 *   
 *   *****************************************************************************************
 *   整个架构默认只处理脚本代码。默认抛弃执行 WEB-INF/classes 中的传统类。除非在配置文件中设置：
 *   <enabled_search_path_classes>true</enabled_search_path_classes>
 *   *****************************************************************************************
 *   
 *   
 * 2018-07-18 修改了日志输出类
 * 2018-09-05 修改了getConfProp()方法，直接从XmlConfigParse类实例中获取。并去掉了setConfProp()方法，因为没有用过。
 * 2018-09-05 构造ResourcesLoader时，不再做复杂基类设置，因为那个时候还没构造基类功能
 * 2018-09-13 简化了整个架构中日志初始化步骤
 *            增加了从配置文件中读取配置，判断是否扫描 WEB-INF/classes 文件夹中的类
 *            
 * 2019-01-24 修改了ClassLoader，增加了集中资源管理服务。简化了程序结构
 * 2019-06-15 在初始化bean报错时，完善了日志信息
 * 2020-04-03 开放了获取日志对象方法，共内部其它类使用
 * 2020-05-12 修改了bcl方法名
 * 2020-08-06 修改了配置文件处理接口，改为直接使用实体类
 *                                         
 * @author 刘虻
 * 2010-1-27 下午03:54:07
 */
@ClassInfo({"2020-08-06 15:11","类加载器"})
public class BeanFactory implements IBeanFactoryManager {
	
	protected HashMap<String,BeanVO>  beanVOMap            = null;                          //类信息容器 key:类主键 value:BeanVO
	protected ArrayList<IBeanFactory> childBeanFacotryList = new ArrayList<IBeanFactory>();	//子类加载器序列
	protected ArrayList<String>       classPathList        = new ArrayList<String>(); 		//类路径序列
	protected ArrayList<String>       configList           = new ArrayList<String>();       //配置文件路径序列（非总配置文件）
	protected String                  configFilePath       = null;                          //配置文件路径       配置文件需要放在类根路径下的某个位置
	protected String                  webInfPath           = null;                          //WEB-INF路径
	protected IBeanFactoryManager     parent               = null;                          //父类加载器
	protected int                     state                = STATE_REST_NONE;              //类加载器状态
	protected XmlConfigParse          xmlConfigParse       = new XmlConfigParse(this);      //配置文件解析类
	private   ILog                    log                  = null;                          //日志文件对象
	protected boolean                 debugMode            = false;                         //是否为调试模式
	protected boolean                 developMode          = false;                         //是否为开发模式
	protected IRemoteBeanFactory      remoteBeanFactory    = null;                          //远程类工厂管理类
	private   ResourceService         rs                   = null;                          //包资源管理服务
	protected BeanClassLoader         bcl                  = null;                          //类加载器
	protected long                    initWaitTimeOut      = 1800000;                       //1800000; //初始化等待时间 （默认30分钟）
	protected ThreadGroup             threadGroup          = null;                          //线程组
	protected String                  projectName          = null;                          //项目名称
	protected String                  projectCode          = null;                          //项目代码
	protected String                  projectPin           = null;                          //项目标识
	
	//加载了 /WEB-INF/lib 中的子文件夹路径序列，
	//可以在程序中用来判断是否加载了指定的子文件夹
	//比如 lib 文件夹中有个 poi 子文件夹，里面是一堆处理excel的包
	//在程序中就可以判断是否存在poi文件夹，来决定是否启用解析excel功能
	protected List<String> extLibPathList = null;
	
	/*
	 * 如果类实例还没有初始化好，等待检测时间信息
	 */
	protected long waitCheckTime  = 1000; //间隔检测时间
	protected int  waitCheckCount = 60;   //检测次数
	
	
	/**
	 * 构造函数
	 * @author 刘虻
	 */
	public BeanFactory() {
		super();
	}
	
	/**
	 * 获取日志对象
	 * 刘虻
	 * 2010-2-3 下午02:24:29
	 * @return 日志对象
	 */
	@Override
    public ILogShadow getLogShadow() {
		if(xmlConfigParse!=null) {
			return xmlConfigParse.logShadow;
		}
		if(parent!=null) {
			return parent.getLogShadow();
		}
		return new NullLogShadow();
	}
	
	/**
	 * 将指定类设置到类加载器中
	 * @param cls 受类加载器管控的类
	 * @param needInit 是否需要初始化这个类（如果不需要，是因为最后统一进行初始化用）
	 * @return 返回类主键
	 * 2016年4月8日
	 * @author 马宝刚
	 */
	@Override
    public String setClass(Class<IBean> cls, boolean needInit) {
	    if(cls==null) {
	        return "";
	    }
	    //这个时候日志类可能还没被初始化
	    System.out.println("Begin Set Class To BeanFactory :["+cls.getName()+"]");
	    
	    //信息容器
	    BeanVO vo = new BeanVO();
	    vo.beanClass = cls;
	    vo.classPath = cls.getName();
	    //从类中获取需要加载处理的信息
	    ClassUtil.getBeanInfoByClass(vo);
	    
	    if(vo.id==null || vo.id.length()<1) {
	        return "";
	    }
	    if(getBeanVOMap().containsKey(vo.id)) {
	        //先获取已经存在的类信息
	        BeanVO oldVO = getBeanVOMap().get(vo.id);
	        try {
	            setObjectState(oldVO,STATE_STOP_BEGIN);
	        }catch(Exception e) {
	            e.printStackTrace();
	        }
	    }
	    //放入容器
	    getBeanVOMap().put(vo.id,vo);
	    if(needInit) {
			try {
				BeanVOUtil.init(this,vo);
				BeanVOUtil.executeAfterStartMethod(this,vo);
				BeanVOUtil.registBean(this,vo);
			}catch(Exception e) {
				//在这里无法拦截到ClassNotFoundException
				e.printStackTrace();
			}	
	    }
        return vo.id;
	}
	
	
	/**
	 * 将类实例设置到类加载器中
	 * 该类实例在类加载器中为常驻类实例,状态为运行中
	 * 刘虻
	 * 2010-5-12 上午11:12:42
	 * @param objInterface 类接口
	 * @param obj 类实例
	 * @throws Exception 执行发生异常
	 */
	@Override
    public void setObject(Class<?> objInterface, Object obj) throws Exception {
		//获取版本信息
		LoadBeanVO lbVO = newLoadBeanVO(objInterface);
		if(lbVO.isError && lbVO.errorMsg!=null) {
			getLog().error(lbVO.errorMsg,BeanException.class);
			return; //不可达代码
		}
		setObject(lbVO.beanID,obj);
	}
	
	
	/**
	 * 构造新的类信息容器
	 * 刘虻
	 * 2010-9-1 下午04:47:43
	 * @param interfaceCls 类接口
	 * @return 类信息容器s
	 */
	protected LoadBeanVO newLoadBeanVO(Class<?> interfaceCls) {
		//构建返回值
		LoadBeanVO lbVO = new LoadBeanVO();
		if(interfaceCls!=null) {
		    //获取类基本信息
		    String[] values = ClassUtil.getBeanInfo(interfaceCls);
		    lbVO.beanID = values[0];
			if(lbVO.beanID==null || lbVO.beanID.length()<1) {
				lbVO.errorMsg = "The InterfaceClass BeanID Info Is Null:["+interfaceCls+"]";
				lbVO.isError = true;
			}
		}else {
			lbVO.errorMsg = "The InterfaceClass is Null";
			lbVO.isError = true;
		}
		return lbVO;
	}
	
	/**
	 * 将类实例设置到类加载器中
	 * 该类实例在类加载器中为常驻类实例,状态为运行中
	 * 刘虻
	 * 2010-5-12 上午10:51:01
	 * @param beanID 类主键
	 * @param factoryID 工厂主键
	 * @param obj 类实例
	 * @throws Exception 执行发生异常
	 */
	public void setObject(
			String beanID,Object obj) throws Exception {
		if(beanID==null || beanID.length()<1) {
			throw new Exception("The BeanID is Null");
		}
		if(obj==null) {
			throw new Exception("setObject Is Null");
		}
		//获取类信息容器
		BeanVO beanVO = null;
		if(beanExists(beanID)) {
			beanVO = getBeanVO(beanID,null);
			if(beanVO!=null) {
				//先停止该类
				setObjectState(beanVO,STATE_STOP_MANUAL_E);
			}
		}
		//构建新的信息容器
		beanVO = new BeanVO();
		beanVO.id = beanID;
		//设置为常驻内存，如果不是常驻内存的类也没有必要调用这个方法
		beanVO.singletonLevel = 1;
		beanVO.bean = obj;
		if(isDebugMode()) {
			beanVO.state = STATE_RUN_TEST;
		}else {
			beanVO.state = STATE_RUN_MORMAL;
		}
		//放入信息容器
		getBeanVOMap().put(beanID,beanVO);
	}
	
	
	/**
	 * 移出指定类
	 * @param beanID 类主键
	 * 2014年7月31日
	 * @author 马宝刚
	 */
	@Override
    public void removeObject(String beanID) {
		if(beanID==null || beanID.length()<1) {
			return;
		}
		//获取类信息容器
		BeanVO beanVO = null;
		if(getBeanVOMap().containsKey(beanID)) {
			beanVO = getBeanVOMap().get(beanID);
			if(beanVO!=null) {
				//先停止该类
				try {
					setObjectState(beanVO,STATE_STOP_MANUAL_E);
				}catch(Exception e) {}
			}
			getBeanVOMap().remove(beanID);
		}else {
			getParent().removeObject(beanID);
		}
	}
	
	
	
	/**
	 * 获取线程组
	 * @author 刘虻
	 * 2008-8-13下午02:43:15
	 * @return 线程组
	 */
	protected ThreadGroup getThreadGroup() {
		if (threadGroup==null) {
			threadGroup = new ThreadGroup("BeanFactory ThreadGroup");
		}
		return threadGroup;
	}
	
	
	/**
	 * 获取有效的配置文件解析类
	 * 刘虻
	 * 2010-2-3 下午01:47:36
	 * @return 有效的配置文件解析类
	 */
	protected XmlConfigParse getXmlConfigParse() {
		return xmlConfigParse;
	}
	
	/**
	 * 获取有效的类信息容器
	 * 刘虻
	 * 2010-2-3 下午01:34:34
	 * @return 有效的类信息容器
	 */
	@Override
    public Map<String,BeanVO> getBeanVOMap() {
		if(beanVOMap==null) {
			beanVOMap = new HashMap<String,BeanVO>();
		}
		return beanVOMap;
	}
	
	/**
	 * 设置配置文件路径
	 * 刘虻
	 * 2010-2-2 下午04:09:39
	 * @param configFilePath 配置文件路径
	 */
	@Override
    public void setConfigFilePath(String configFilePath) {
		//可能在jar包中，而factoryBasePath可能是jar包所在的文件路径
		if(configFilePath!=null && configFilePath.length()>0 
				&&webInfPath!=null && webInfPath.length()>0) {
			configFilePath = SFilesUtil.getAllFilePath(configFilePath,webInfPath);
		}
		this.configFilePath = configFilePath;
	}

	
	/**
	 * 设置WEB-INF文件夹路径
	 * 刘虻
	 * 2010-9-10 下午04:11:21
	 * @param webInfPath WEB-INF文件夹路径
	 */
	@Override
    public void setWebInfPath(String webInfPath) {
		this.webInfPath = webInfPath;
	}
	
	
	/**
	 * 获取子类工厂序列
	 * element:value:IBeanFactoryManager
	 * 刘虻
	 * 2010-4-21 上午11:15:13
	 * @return 子类工厂序列
	 */
	@Override
    public List<IBeanFactory> getChildBeanFactoryList() {
		return childBeanFacotryList;
	}
	
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-1-27 下午03:54:07
	 */
	@Override
    public void destroy(int state) throws Exception {
		getLog().warning("Begin Destroy The BeanFactory Code:"+state,null);
		getLog().warning(LogUtil.getStackTraceString(this),null);
		if(state<STATE_STOP_BEGIN || state>STATE_STOP_END) {
			state = STATE_STOP_AUTO_E;
		}
		this.state = state;
		doDestroy(state); //执行停止
		
		configFilePath = null;
		beanVOMap = null;
		childBeanFacotryList = new ArrayList<IBeanFactory>();
		classPathList = new ArrayList<String>();
		configList = new ArrayList<String>();
		xmlConfigParse = null;
		getLog().destroy();
		log = null;
		bcl = null; //释放类加载器
		//标记停止状态
		state = STATE_REST_NONE;
	}

	
	/**
	 * 执行停止
	 * 刘虻
	 * 2010-5-6 下午05:51:55
	 * @throws Exception 停止
	 */
	protected void doDestroy(int state) throws Exception {
		//获取主键序列
		List<String> idList = BaseUtil.getMapKeyList(getBeanVOMap());
		//错误信息缓存
		StringBuffer errorMsg = new StringBuffer();
		BeanVO beanVO; //元素
		for(int i=0;i<idList.size();i++) {
			//获取类信息容器
			beanVO = getBeanVOMap().get(idList.get(i));
			if(beanVO==null) {
				continue;
			}
			try {
				setObjectState(beanVO,state);
			}catch(Exception e) {
				e.printStackTrace();
				errorMsg
					.append("\nDestroy Bean ID:[")
					.append(beanVO.id)
					.append("] Exception:[")
					.append(e)
					.append("]");
			}
		}
		for(IBeanFactory bf:childBeanFacotryList) {
			if(bf==null) {
				continue;
			}
			try {
				bf.destroy(state);
			}catch(Exception e) {
				e.printStackTrace();
				errorMsg
					.append("\nDestroy Exception:[")
					.append(e)
					.append("]");
			}
		}
		if(errorMsg.length()>0) {
			throw new BeanException(errorMsg.toString());
		}
		beanVOMap = null;
		xmlConfigParse = null;
	}
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-1-27 下午03:54:07
	 */
	@Override
    public void reset(int state) throws Exception {
		getLog().warning("Begin Reset The BeanFactory Code:"+state,null);
		if(state<STATE_RESET_BEGEN || state>STATE_RESET_END) {
			state = STATE_RESET_AUTO_E;
		}
		this.state = state;
		if(state==STATE_RESET_AUTO_E) {
			doDestroy(STATE_STOP_AUTO_E); //执行停止 自动状态
		}else if(state==STATE_RESET_MANUAL_E) {
			doDestroy(STATE_STOP_MANUAL_E); //执行停止 手动状态
		}else {
			doDestroy(STATE_STOP_EXCEPTION_E); //执行停止 异常
		}
		if(configFilePath!=null && configFilePath.length()>0) {
			//构建返回值
			initBeanVOList(
					xmlConfigParse.addBeanVO(configFilePath,getBeanVOMap()));
			if(debugMode) {
				state = STATE_RUN_TEST; //调试运行中
			}else {
				state = STATE_RUN_MORMAL; //正常运行中
			}
		}
		if(configList!=null) {
			for(String configPath:configList) {
				if(configPath==null || configPath.length()<1) {
					continue;
				}
				initBeanVOList(
						xmlConfigParse.addBeanVO(configPath,getBeanVOMap()));
			}
		}
		if(debugMode) {
			state = STATE_RUN_TEST; //调试运行中
		}else {
			state = STATE_RUN_MORMAL; //正常运行中
		}
		commitInitBean(null); //提交
		getLog().warning("Reset The BeanFactory Completed,Code:"+state,null);
	}
	
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-1-27 下午03:54:07
	 */
	@Override
    public String getWebInfPath() {
		if(webInfPath==null) {
			webInfPath = "";
		}
		return webInfPath;
	}

	/**
	 * 该类不能常住内存，因为类中保存着部署信息数据，每次部署，数据都不同
	 * 获取有效的影子类实例工具
	 * 刘虻
	 * 2010-4-29 下午03:14:53
	 * @return 有效的影子类实例工具
	 */
	protected ShadowBeanUtil getShadowBeanUtil() {
		//构建影子类实例工具
		ShadowBeanUtil shadowBeanUtil = new ShadowBeanUtil(this);
		//shadowBeanUtil.setDeleteSourceFile(false);
		//shadowBeanUtil.setEncoding("UTF-8");
		return shadowBeanUtil;
	}
	
	/**
	 * 判断指定类是否实现了指定接口(递归调用)
	 * 刘虻
	 * 2010-5-6 下午02:39:28
	 * @param objCls 指定类
	 * @param interfaceCls 指定接口
	 * @return true实现 
	 */
	protected boolean instanceofInterface(Class<?> objCls,Class<?> interfaceCls) {
		if(objCls==null || interfaceCls==null) {
			return false;
		}
		if(objCls.getName().equals(interfaceCls.getName())) {
			return true;
		}
		//获取指定类实现的接口类数组
		Class<?>[] clss = objCls.getInterfaces();
		if(clss==null || clss.length<1) {
			return false;
		}
		for(int i=0;i<clss.length;i++) {
			if(clss[i]==null) {
				continue;
			}
			if(instanceofInterface(clss[i],interfaceCls)) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-1-27 下午03:54:07
	 */
	@Override
    public <T> T getObject(Class<T> objInterface, Object loader) throws Exception {
		//获取版本信息
		LoadBeanVO lbVO = newLoadBeanVO(objInterface);
		if(lbVO.isError && lbVO.errorMsg!=null) {
			getLog().error(lbVO.errorMsg,BeanException.class);
			return null; // 不可达代码
		}
		//构建返回类实例
		T reObj = getObject(lbVO.beanID,loader);
		if(reObj==null) {
			return null;
		}
		if(instanceofInterface(reObj.getClass(),objInterface)) {
			return reObj;
		}
		//设置影子类
		return getShadowBeanUtil()
					.getShadowObject(reObj,objInterface,getWebInfPath());
	}
	
	/**
	 * 强制转换非当前类加载器的类实例为本地类实例
	 * 刘虻
	 * 2011-1-4 下午05:50:29
	 * @param objInterface 指定接口(本地化接口)
	 * @param loader 类实例（可以使非本模块类实例）
	 * @return 转换后的类实例（可能是影子类）
	 * @throws Exception 执行发生异常
	 */
	@Override
    public Object transformInstance(
			Class<?> objInterface,Object bean) throws Exception {
		if(bean==null) {
			return null;
		}
		if(instanceofInterface(bean.getClass(),objInterface)) {
			return bean;
		}
		//设置影子类
		return getShadowBeanUtil()
					.getShadowObject(bean,objInterface,getWebInfPath());
	}

	/**
	 * 通过类信息容器获取类实例
	 * 刘虻
	 * 2010-2-11 下午04:22:22
	 * @param beanVO 类信息容器
	 * @param beanID 类主键（用于输出错误日志）
	 * 
	 * 防止交叉锁死，允许返回还没被初始化完的类实例（还没执行完初始化方法的类实例）
	 * @param notInited 是否获取还没有被初始化完的类实例
	 * 
	 * @return 类实例
	 * @throws Exception 执行发生异常
	 */
	protected <T> T getObjectFromVO(
			BeanVO beanVO,String beanID,boolean notInited) throws Exception {
		if(beanVO==null) {
			getLog().error("Not Found The Bean ID:["
					+beanID+"]",null);
			return null;
		}
		T reObj = null; //构建返回值
		if(beanVO.state>=STATE_RUN_BEGIN && beanVO.state<=STATE_RUN_END) {
			/*
			 * 运行中
			 */
			reObj = BeanVOUtil.getBean(this,beanVO);
			if(reObj==null) {
				if(beanVO.errorMsg==null) {
					beanVO.errorMsg = "";
				}
				beanVO.errorMsg += " The Bean ID:["+beanID+"] State Is Running But Instance Is Null"; //设置默认错误信息
				beanVO.errorCode = "500001"; //设置错误代码
				beanVO.state = STATE_EXCEPTION_LOAD;
				getLog().error(beanVO.errorMsg,null);
			}
			return reObj;
		}else if(beanVO.state>=STATE_REST_BEGIN 
						&& beanVO.state<=STATE_REST_END) {
			/*
			 * 停止
			 */
			beanVO.state = STATE_EXCEPTION_LOAD;
			if(beanVO.errorMsg==null) {
				beanVO.errorMsg = "";
			}
			beanVO.errorMsg += " The Bean ID:["+beanVO.id+"] Was Stoped Or UnLoaded";
			beanVO.errorCode = "500002";
			getLog().error(beanVO.errorMsg,null);
			return null;
		}else if(beanVO.state>=STATE_START_BEGIN 
					&& beanVO.state<=STATE_START_END) {
			if(notInited) {
				//返回还没被初始化完的类
				return BeanVOUtil.getBean(this,beanVO);
			}
			/*
			 * 启动中
			 */
			return checkWait(beanVO);
		}else if(beanVO.state>=STATE_PAUST_BEGIN 
						&& beanVO.state<=STATE_PAUST_END) {
			/*
			 * 暂停
			 */
			if(beanVO.state==STATE_PAUSE_EXCEPTION_E) {
				//遇到暂停抛出异常
				beanVO.state = STATE_EXCEPTION_LOAD;
				if(beanVO.errorMsg==null) {
					beanVO.errorMsg = "";
				}
				beanVO.errorMsg = " The Bean ID:["+beanVO.id+"] Was Paused";
				beanVO.errorCode = "500003";
				getLog().error(beanVO.errorMsg,null);
				return null;
			}
			return checkWait(beanVO);
		}else if(beanVO.state>=STATE_STOP_BEGIN 
					&& beanVO.state<=STATE_STOP_END) {
			/*
			 * 停止中
			 */
			//正在停止
			beanVO.state = STATE_EXCEPTION_LOAD;
			if(beanVO.errorMsg==null) {
				beanVO.errorMsg = "";
			}
			beanVO.errorMsg += " The Bean ID:["+beanVO.id+"] Is Stopping";
			beanVO.errorCode = "500004";
			getLog().error(beanVO.errorMsg,null);
			return null;
		}else if(beanVO.state>=STATE_RESET_BEGEN && beanVO.state<=STATE_RESET_END) {
			/*
			 * 重启
			 */
			return checkWait(beanVO);
		}else if(beanVO.state>=STATE_EXCEPTION_BEGIN 
						&& beanVO.state<=STATE_EXCEPTION_END) {
			/*
			 * 异常
			 */
			beanVO.state = STATE_EXCEPTION_LOAD;
			if(beanVO.errorMsg==null) {
				beanVO.errorMsg = "";
			}
			beanVO.errorMsg += " The Bean ID:["+beanVO.id+"] Has Exception";
			beanVO.errorCode = "500004";
			getLog().error(beanVO.errorMsg,null);
			return null;
		}
		return null;
	}
	
	
	/**
	 * 检测如果类正在初始化，则等待
	 * 刘虻
	 * 2010-2-12 上午09:57:11
	 * @param beanVO 类信息容器
	 * @return 类实例
	 */
	protected <T> T checkWait(BeanVO beanVO) {
		try {
			for(int i=0;i<waitCheckCount;i++) {
				Thread.sleep(waitCheckTime); //等待
				if((beanVO.state>=STATE_START_BEGIN 
						&& beanVO.state<=STATE_START_END) 
							|| beanVO.state==STATE_PAUSE_WAIT_E) {
					//如果还是启动中，或者是暂停（等待回复），则继续等待
					continue;
				}
				if(beanVO.state>=STATE_RUN_BEGIN && beanVO.state<=STATE_RUN_END) {
					return BeanVOUtil.getBean(this,beanVO);
				}
				getLog().warning("Get Object ID:["+beanVO.id
						+"] Wait Error,State:["+beanVO.state+"]",null);
				return null;
			}
		}catch(Exception e) {}
		getLog().warning("Get Object ID:["+beanVO.id
				+"] Wait Time Out,State:["+beanVO.state+"] "+beanVO.hashCode(),null);
		return null;
	}
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-2-12 上午11:07:59
	 */
	@Override
    public void setBeanException(
			Class<?> objInterface,String exceptionInfo) throws Exception {
		//获取加载信息类
		LoadBeanVO lbVO = newLoadBeanVO(objInterface);
		if(lbVO.isError && lbVO.errorMsg!=null) {
			getLog().error(lbVO.errorMsg,BeanException.class);
			return; //不可达代码
		}
		//获取信息容器
		BeanVO beanVO = getBeanVO(lbVO.beanID,null);
		if(beanVO==null) {
			getLog().warning("Not Find The Bean ID:["+lbVO.beanID+"]",null);
		}
		beanVO.state = STATE_EXCEPTION_RUN;
		beanVO.errorMsg = exceptionInfo;
	}
	
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-1-27 下午03:54:07
	 */
	@Override
    public IBeanFactoryManager getParent() {
		return parent;
	}
	
	/**
	 * 获取根类加载器
	 * 刘虻
	 * 2010-8-12 上午10:32:52
	 * @return 根类加载器
	 */
	@Override
    public IBeanFactoryManager getRoot() {
		if(parent==null || parent.equals(this)) {
			return this;
		}
		return parent.getRoot();
	}
	
	/**
	 * 获取内部的类加载器
	 * 刘虻
	 * 2010-5-7 下午02:03:40
	 * @return 内部的类加载器
	 */
	@Override
    public ClassLoader getClassLoader() {
		if(bcl==null) {
			bcl = new BeanClassLoader(this.getClass().getClassLoader(),getResourceService());
			//执行加载 /WEB-INF/lib 文件夹中，子文件夹内的jar包和zip包
			//如果子文件夹中存在.disabled文件，则忽略该文件夹
			extLibPathList = bcl.loadLibChildPath(getWebInfPath()+"/lib");
    		if(extLibPathList.size()>0) {
    			//构造日志信息
    			StringBuffer extLibPathSbf = new StringBuffer();
    			for(String path:extLibPathList) {
    				extLibPathSbf.append("[").append(path).append("]\n");
    			}
    			getLog().startLog("\n\n*********** Load /WEB-INF/lib Child Path Lib Files ***********\n\n"+extLibPathSbf
    					        +"\n**************************************************************\n\n");
    		}
		}
		return bcl;
	}
	
	/**
	 * 设置父类加载器
	 * 刘虻
	 * 2010-2-2 下午05:14:17
	 * @param beanFactory 父类加载器
	 */
	@Override
    public void setParent(IBeanFactoryManager beanFactory) {
		parent = beanFactory;
		//构建新的类加载器
		bcl = new BeanClassLoader(this.getClass().getClassLoader(),getResourceService());
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-1-27 下午03:54:07
	 */
	@Override
    public int getState() {
		return state;
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-1-27 下午03:54:07
	 */
	@Override
    public List<String> init(boolean debugMode) throws Exception {
		this.debugMode = debugMode;
		state = STATE_START_E; //启动中
		//执行到这里时，一定设置了WEB-INF的路径
		if(webInfPath!=null && !beanExists(ResourcesLoader.class)) {
			ResourcesLoader rl =  new ResourcesLoader();
			rl.load(webInfPath);
			//放入类工厂
			setObject(ResourcesLoader.class,rl);
		}
		if(configFilePath==null || configFilePath.length()<1) {
			configFilePath = "!/resfiles/base.xml";
		}
		//构建返回值
		List<String> reList = initBeanVOList(xmlConfigParse.addBeanVO(configFilePath,getBeanVOMap()));
		if(debugMode) {
			state = STATE_RUN_TEST; //调试运行中
		}else {
			state = STATE_RUN_MORMAL; //正常运行中
		}
		return reList;
	}
	
	
	/**
	 * 初始化刚加载信息的类序列
	 * 刘虻
	 * 2010-2-10 上午09:24:08
	 * @param beanIdList 类主键序列
	 * @return 初始化后的类主键序列
	 * @throws Exception 执行发生异常
	 */
	protected List<String> initBeanVOList(List<String> beanIdList) throws Exception {
		//构建返回值
		ArrayList<String> reList = new ArrayList<String>();
		
		if(beanIdList==null) {
			return reList;
		}
		//排序容器
		SortVector<BeanVO> sv = new SortVector<BeanVO>();
		BeanVO beanVO; //元素
		for(String beanID:beanIdList) {
			if(beanID==null || beanID.length()<1) {
				continue;
			}
			//初始化类
			// 将自定义初始化归类到初始化 取消类型1
			// 原来是，先统一做初始化，然后等待全部初始化完毕后在统一进行自定义初始化。
			// 自定义初始化与初始化连在一起执行，因为有的类在初始化时要引用别的类，如果那个
			// 类需要做自定义初始化就会导致阻塞无法继续进行
			beanVO = getBeanVOMap().get(beanID);
			if(beanVO==null) {
				throw new BeanException("Not Find The Bean ID:["+beanID+"]");
			}
			if((beanVO.state<STATE_REST_BEGIN 
					|| beanVO.state>STATE_REST_END) 
					&& beanVO.state!=STATE_START_LOADINFO_OK) {
				//非停止状态
				continue;
			}
			sv.add(beanVO,beanVO.singletonLevel);
			reList.add(beanID);
		}
		
		sv.desc(); //优先执行顺序，由大到小
		//错误信息缓存
		StringBuffer errorMsgSbf = new StringBuffer();
		getLog().startLog("-----------------------Begin Init Beans...");
		while(sv.hasNext()) {
			beanVO = sv.nextValue();
			getLog().startLog("init The Bean：["+beanVO.id+"] ClassTitle:["+beanVO.classTitle+"] ClassPath:["+beanVO.classPath+"]");
			try {
				BeanVOUtil.init(this,beanVO);
			}catch(Exception e) {
				errorMsgSbf.append(DebugUtil.getExceptionInfo(e,"\n")).append("\n");
			}
		}
		getLog().startLog("\n\n( ^3^ )╱~~  BeanFactory Init Bean Completed!\n\n");
		
		if(errorMsgSbf.length()>0) {
			throw new BeanException(errorMsgSbf.toString());
		}
		return reList;
	}
	
	

	
	/**
	 * 是否为调试模式
	 * 刘虻
	 * 2010-3-30 下午06:00:16
	 * @return 调试模式
	 */
	@Override
    public boolean isDebugMode() {
		return debugMode;
	}
	
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-2-3 下午02:22:14
	 */
	@Override
    public List<String> addBean(String configFilePath) throws Exception {
		if(!configList.contains(configFilePath)) {
			configList.add(configFilePath);
		}
		//添加新的类 并且执行初始化
		return initBeanVOList(
				xmlConfigParse.addBeanVO(configFilePath,getBeanVOMap()));
	}
	
	
	/**
	 * 通过类文件路径，构造指定类，尝试获取类内部的（或其父类的 ) PARENT_BEAN_ID 
	 * 值，通过该值获取其父配置信息，按照父配置信息配置当前类
	 * 刘虻
	 * 2012-12-11 下午3:41:36
	 * @param classFilePath 类文件路径
	 * @return 加载后的类主键
	 */
	@Override
    public String addBeanByClassFilePath(String classFilePath) {
		return addBeanByClassFilePath(classFilePath,null);
	}

	/**
	 * 通过类文件路径，构造指定类，尝试获取类内部的（或其父类的 ) PARENT_BEAN_ID 
	 * 值，通过该值获取其父配置信息，按照父配置信息配置当前类
	 * 刘虻
	 * 2012-12-11 下午3:41:36
	 * @param classFilePath 类文件路径
	 * @param cl 专用类加载器
	 * @return 加载后的类主键
	 */
	@Override
    public String addBeanByClassFilePath(String classFilePath, ClassLoader cl) {
		//构造指定信息容器
		BeanVO beanVO = 
				xmlConfigParse.addBeanVOFromClassFilePath(classFilePath,getBeanVOMap(),cl);
		if(beanVO==null) {
			return null;
		}
		try {
			//执行初始化
			BeanVOUtil.init(this,beanVO);
			return beanVO.id;
		}catch(Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	/**
	 * 判断指定类是否存在
	 * 刘虻
	 * 2010-4-21 下午01:09:42
	 * @param beanID 类主键
	 * @return 指定类是否存在
	 */
	@Override
    public boolean beanExists(String beanID) {
		//构建返回值
		boolean reBoo = 
			getBeanVOMap().containsKey(beanID);
		if(reBoo) {
			return true;
		}
		if(getParent()!=null) {
			return getParent().beanExists(beanID);
		}
		return false;
	}
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-4-12 下午06:42:17
	 */
	@Override
    public boolean beanExists(Class<?> objInterface) {
		//获取版本信息
		LoadBeanVO lbVO = newLoadBeanVO(objInterface);
		if(lbVO.isError) {
			return false;
		}
		return beanExists(lbVO.beanID);
	}
	

	
	/**
	 * 添加其它类路径(全路径)
	 * 刘虻
	 * 2010-2-10 下午01:38:59
	 * @param classPath 类路径(全路径)
	 */
	@Override
    public void addClassPath(String classPath) {
		if(classPath==null 
				|| classPath.length()<1 
				|| classPathList.contains(classPath)) {
			return;
		}
		
		String[] paths; //全路径数组
		if(":".equals(File.pathSeparator)) {
			//Linux系统
			paths = BaseUtil.split(classPath,":",";");
		}else {
			//Windows系统
			paths = BaseUtil.split(classPath,";");
		}
		for(int i=0;i<paths.length;i++) {
			classPathList.add(paths[i]);
			((BeanClassLoader)getClassLoader()).addClassPath(paths[i]);
		}
	}

	/**
	 * 获取其它类路径序列（全文件路径）
	 * @return 其它类路径序列（全文件路径）
	 * 2016年11月7日
	 * @author MBG
	 */
	@Override
    public List<String> getClassPathList(){
		return classPathList;
	}
	
	/**
	 * 加入新的资源文件
	 * 
	 * 热替换类时，需要将管理类中的类加载器变成新的，否则构建类时，因为旧的类
	 * 已经加载过，会抛重复加载的异常
	 * 
	 * 刘虻
	 * 2010-10-29 下午03:49:38
	 * @param basePath 类路径
	 * @param file 类文件对象
	 */
	@Override
    public void addNewSource(String basePath, File file) {
		bcl = new BeanClassLoader(bcl,getResourceService());
		bcl.addSource(basePath,file);
	}
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-3-30 下午03:31:11
	 */
	public int getObjectState(String beanID,String factoryID) throws Exception {
		//获取类信息容器
		BeanVO beanVO = getBeanVO(beanID,factoryID);
		if(beanVO!=null) {
			return beanVO.state;
		}
		return STATE_REST_BEGIN;
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-2-2 下午06:00:06
	 */
	@Override
    public int getObjectState(Class<?> objInterface) throws Exception {
		//获取类信息容器
		BeanVO beanVO = getBeanVO(objInterface,null);
		if(beanVO!=null) {
			return beanVO.state;
		}
		return STATE_REST_BEGIN;
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-2-2 下午06:00:10
	 */
	@Override
    public void setObjectState(
			Class<?> objInterface,int state) throws Exception {
		setObjectState(getBeanVO(objInterface,null),state);
	}
	
	
	
	/**
	 * 设置类状态（包括可执行状态，比如 停止中，重启等）
	 * 刘虻
	 * 2010-3-31 下午03:03:53
	 * @param beanVO 类信息容器
	 * @param state 状态
	 * @throws Exception 执行发生异常
	 */
	protected void setObjectState(
			BeanVO beanVO,int state) throws Exception {
		if(beanVO==null) {
			return;
		}
		if(state>=STATE_STOP_BEGIN && state<=STATE_STOP_END) {
			/*
			 * 执行停止
			 */
			if(beanVO.destoryMethodName!=null 
					&& beanVO.destoryMethodName.length()>0) {
				//需要执行停止的方法
				getLog().log(
						"Begin Destroy Bean ID:["+beanVO.id+"]");
				BeanVOUtil.executeDestroyMethod(beanVO);
			}
		}else if(state>=STATE_RESET_BEGEN && state<=STATE_RESET_END) {
			/*
			 * 执行重启
			 */
			if(beanVO.destoryMethodName!=null 
					&& beanVO.destoryMethodName.length()>0) {
				//需要执行停止的方法
				getLog().log(
						"Begin Destroy Bean ID:["+beanVO.id+"]");
				BeanVOUtil.executeDestroyMethod(beanVO);
			}
			xmlConfigParse.resetBeanVO(beanVO);
			//尝试获取一次
			BeanVOUtil.getBean(this,beanVO);
		}else if(state>=STATE_START_BEGIN && state<=STATE_START_END) {
			/*
			 * 执行启动
			 */
			if(beanVO.state>=STATE_PAUST_BEGIN 
					&& beanVO.state<=STATE_PAUST_END) {
				//恢复暂停只需要设置一下状态
				beanVO.state = state; //设置状态值
				return;
			}
			if(!beanVO.isParent) {
				//父类就没必要启动了
				BeanVOUtil.getBean(this,beanVO);
				return;
			}
		}else if(state>=STATE_PAUST_BEGIN && state<=STATE_PAUST_END) {
			/*
			 * 执行暂停
			 */
			//暂停无任何处理动作，直接标识状态
		}
		beanVO.state = state; //设置状态值
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-2-9 下午05:53:29
	 */
	@Override
    public void addChildBeanFactory(IBeanFactory beanFactory) {
		if(beanFactory==null) {
			getLog().warning("Add Bean Factory Is Null",null);
			return;
		}
		if(!childBeanFacotryList.contains(beanFactory)) {
			childBeanFacotryList.add(beanFactory);
		}
	}
	
	
	/**
	 * 获取一个新构建的子类加载器
	 * 刘虻
	 * 2010-4-22 下午05:57:53
	 * @param factoryID 新的子类加载器主键
	 * @param factoryBasePath 工厂类根路径
	 * @return 新的子类加载器
	 * @throws Exception 执行发生异常
	 */
	@Override
    public IBeanFactoryManager getNewChildBeanFactory(String factoryBasePath) throws Exception {
		//构建新的类实例
		BeanFactory cbf = new BeanFactory();
		cbf.setParent(this);
		cbf.webInfPath = getWebInfPath();
		cbf.addClassPath(factoryBasePath);
		if(!childBeanFacotryList.contains(cbf)) {
			childBeanFacotryList.add(cbf);
		}
		return cbf;
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-3-1 下午04:37:11
	 */
	@Override
    public IRemoteBeanFactory getRemoteBeanFactory() {
		return remoteBeanFactory;
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-3-1 下午04:37:17
	 */
	@Override
    public void setRemoteBeanFactory(IRemoteBeanFactory remoteBeanFactory) {
		this.remoteBeanFactory = remoteBeanFactory;
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-4-2 下午04:33:21
	 */
	@Override
    public BeanVO getBeanVO(String beanID, Object loader) throws Exception {
		if(state>=STATE_STOP_BEGIN && state<=STATE_STOP_END) {
			throw new Exception("The Bean Factory Stopped");
		}
		//尝试在本地类加载器中获取
		BeanVO reBeanVO = getBeanVOMap().get(beanID);
		if(reBeanVO!=null) {
			return reBeanVO;
		}
		if(parent!=null) {
			return getParent().getBeanVO(beanID,loader);
		}
		return null;
	}
	
	
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-3-31 上午11:02:59
	 */
	@Override
    public BeanVO getBeanVO(Class<?> objInterface, Object loader) throws Exception {
		//获取版本信息
		LoadBeanVO lbVO = newLoadBeanVO(objInterface);
		if(lbVO.isError && lbVO.errorMsg!=null) {
			getLog().error(lbVO.errorMsg,BeanException.class);
			return null; //不可达代码
		}
		return getBeanVO(lbVO.beanID,loader);
	}

	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-4-2 下午01:02:13
	 */
	@Override
    public void setSingletonObject(
			String beanID,Object bean,String destroyMethod) {
		if(beanID==null || beanID.length()<1 || bean==null) {
			return;
		}
		//构建类信息容器
		BeanVO beanVO = new BeanVO();
		beanVO.id = beanID;
		beanVO.bean = bean;
		beanVO.singletonLevel = 1;
		if(debugMode) {
			beanVO.state = STATE_RUN_TEST;
		}else {
			beanVO.state = STATE_RUN_MORMAL;
		}
		beanVO.destoryMethodName = destroyMethod;
	}

	/**
	 * @deprecated 在项目开发时禁止使用
	 * 因为无法通过程序获取类之间的依赖性
	 * 覆盖方法
	 * 刘虻
	 * 2010-4-14 下午03:25:56
	 */
	@Override
    public <T> T getObject(String beanID, Object loader) throws Exception {
        if(beanID==null || beanID.length()<1) {
            //构建错误信息
            String errorMsg = "Load Bean ID is Null";
            getLog().error(errorMsg,null);
            throw new BeanException(errorMsg);
        }
        //获取类信息容器
        BeanVO beanVO = getBeanVO(beanID,loader);
        if(beanVO==null) {
            //构建错误信息
            String errorMsg = 
                "The Bean ID:["+beanID+"] Not Found. Loader:["+loader+"]";
            getLog().error(errorMsg,null);
            throw new BeanException(errorMsg);
        }
        return getObjectFromVO(beanVO,beanID,false);
	}
	
	
	/**
	 * @deprecated 框架内部调用方法
	 * 注意：该方法返回的类实例通常为需要调用初始化方法，常驻内存的服务
	 *       ，由于在启动时可能会遇到交叉调用，比如类实例A在调用初始化方法
	 *       内部加载了类实例B，但是类实例B还在调用初始化方法，没有结束初始化
	 *       就会导致锁死
	 * @param cls         目标类型
	 * @param loader      调用者
	 * @return            目标类实例
	 * @throws Exception  异常
	 * 2016年12月14日
	 * @author MBG
	 */
	@Override
    public Object getNativeObject(Class<?> cls, Object loader) throws Exception {
		//获取版本信息
		LoadBeanVO lbVO = newLoadBeanVO(cls);
		if(lbVO.isError && lbVO.errorMsg!=null) {
			getLog().error(lbVO.errorMsg,BeanException.class);
			return null; //不可达代码
		}
		BeanVO beanVO = getBeanVO(lbVO.beanID,loader);
        if(beanVO==null) {
            //构建错误信息
            String errorMsg = 
                "The Bean ID:["+lbVO.beanID+"] Not Found. Loader:["+loader+"]";
            getLog().error(errorMsg,null);
            throw new BeanException(errorMsg);
        }
        return getObjectFromVO(beanVO,lbVO.beanID,true);
	}
	
	

	/**
	 * 执行注册类
	 * 刘虻
	 * 2010-11-5 上午11:07:57
	 * @throws Exception 执行发生异常
	 */
	@Override
    public void doRegistBeans(List<String> beanPKList) throws Exception {
		if(beanPKList==null) {
			//获取类信息主键
			beanPKList = BaseUtil.getMapKeyList(getBeanVOMap());
		}
		getLog().startLog("\n---------------------------\nBegin Regist Bean ...\n---------------------------\n");
		BeanVO beanVO; //元素
		for(int i=0;i<beanPKList.size();i++) {
			//获取类信息容器
			beanVO = getBeanVOMap().get(beanPKList.get(i));
			if(beanVO==null || beanVO.isParent || beanVO.beanRegister==null || beanVO.beanRegister.length()<1) {
				continue;
			}
			getLog().startLog("Regist Bean:["+beanVO.id+" "+beanVO.classPath+" "+beanVO.classTitle+"] To:["+beanVO.beanRegister+"]");
			BeanVOUtil.registBean(this,beanVO); //执行注册类
		}
		getLog().startLog("\n\n( ^3^ )╱~~  BeanFactory Regist Bean Completed!\n\n");
		for(IBeanFactory bf:getChildBeanFactoryList()) {
			if(bf==null) {
				continue;
			}
			((IBeanFactoryManager)bf).doRegistBeans(null);
		}
	}
	
	/**
	 * 执行启动后执行的方法
	 * 刘虻
	 * 2010-11-5 上午11:08:10
	 * @throws Exception 执行发生异常
	 */
	@Override
    public void doBeansAfterStartMethod(List<String> beanPKList) throws Exception {
		if(beanPKList==null) {
			//获取类信息主键
			beanPKList = BaseUtil.getMapKeyList(getBeanVOMap());
		}
		SortVector<BeanVO> sv = new SortVector<BeanVO>(); //排序序列
		BeanVO beanVO; //元素
		for(int i=0;i<beanPKList.size();i++) {
			//获取类信息容器
			beanVO = getBeanVOMap().get(beanPKList.get(i));
			if(beanVO==null) {
				continue;
			}
			if(beanVO.afterStartMethodName==null 
					|| beanVO.afterStartMethodName.length()<1) {
				continue;
			}
			sv.add(beanVO,beanVO.singletonLevel);
		}
		
		sv.desc(); //优先级由大到小
		getLog().startLog("\n---------------------------\nBegin Do AfterStart Method ...\n---------------------------\n");
		while(sv.hasNext()) {
			beanVO = sv.nextValue();
			getLog().startLog("Do AfterStart Bean:["+beanVO.id+"] Method:["+beanVO.afterStartMethodName+"]");
			BeanVOUtil.executeAfterStartMethod(this,beanVO);
		}
		getLog().startLog("\n\n( ^3^ )╱~~  BeanFactory Do AfterStart Method Completed!\n\n");
		for(IBeanFactory bf:getChildBeanFactoryList()) {
			if(bf==null) {
				continue;
			}
			((IBeanFactoryManager)bf).doBeansAfterStartMethod(null);
		}
	}
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-4-28 上午11:08:59
	 */
	@Override
    public void commitInitBean(List<String> beanIdList) throws Exception {
		if(parent!=null && parent!=this) {
			//只有根类加载器才能执行提交
			return;
		}
		doBeansAfterStartMethod(beanIdList);
		doRegistBeans(beanIdList);
		outErrorBean(beanIdList); //输出初始化报错的类信息
		state = IBeanFactory.STATE_RUN_BEGIN; //标记启动完毕
	}
	
	
	/**
	 * 判断类加载器是否启动完毕（运行中）
	 * @return 类加载器是否启动完毕（运行中
	 * 2016年6月13日
	 * @author MBG
	 */
	@Override
    public boolean isStartRun() {
		return (state==IBeanFactory.STATE_RUN_BEGIN);
	}
	
	/**
	 * 输出初始化报错的类信息
	 * 2015年11月4日
	 * @author 马宝刚
	 */
	protected void outErrorBean(List<String> keyList) {
	    StringBuffer errSbf = new StringBuffer(); //错误信息
	    if(keyList==null) {
		    //获取类主键序列
		    keyList = BaseUtil.getMapKeyList(getBeanVOMap());
	    }
	    BeanVO vo; //元素
	    
	    for(String key:keyList) {
	        vo = getBeanVOMap().get(key);
	        if(vo==null) {
	            continue;
	        }
	        if(vo.error) {
	            errSbf.append("BeanID:["+vo.id+"] "+vo.errorMsg);
	        }
	    }
	    if(errSbf.length()>0) {
	        log.startLog("\n\n******************************************************************\n=-=-=-=-=-=Load Bean Error=-=-=-=-=-=\n\n"
	                    +errSbf+"\n******************************************************************\n\n");
	    }
	}
	
	/**
	 * 设置初始化等待时间
	 * 刘虻
	 * 2010-5-10 下午03:31:05
	 * @param initWaitTimeOut 初始化等待时间
	 */
	public void setInitWaitTimeOut(long initWaitTimeOut) {
		this.initWaitTimeOut = initWaitTimeOut;
	}
	
	/**
	 * 返回当前项目名（中文标题）
	 * 在WEB-INF/resfiles/properties.xml 中 <project_name></project_name>
	 * 用来区分测试环境、生产环境、开发环境、集群中的每台服务器
	 * @return 当前项目名
	 * 2018年1月25日
	 * @author MBG
	 */
	@Override
    public String getProjectName() {
		if(projectName==null) {
			projectName = "";
		}
		return projectName;
	}
	
	/**
	 * 返回当前项目代码（英文字符串）
	 * 在WEB-INF/resfiles/properties.xml 中 <project_code></project_code>
	 * 用来区分测试环境、生产环境、开发环境、集群中的每台服务器
	 * 用在在线开发平台的授权码验证
	 * @return 当前项目代码
	 * 2018年1月25日
	 * @author MBG
	 */
	@Override
    public String getProjectCode() {
		if(projectCode==null) {
			projectCode = "";
		}
		return projectCode;
	}
	
	/**
	 * 返回当前项目标识（通常为两个大写字母）
	 * 在WEB-INF/resfiles/properties.xml 中 <project_pin></project_pin>
	 * 用来区分测试环境、生产环境、开发环境、集群中的每台服务器
	 * 用在脚本名后缀，数据主键前缀等
	 * @return
	 * 2018年1月25日
	 * @author MBG
	 */
	@Override
    public String getProjectPin() {
		if(projectPin==null) {
			projectPin = "";
		}
		return projectPin;
	}
	
	
	/**
	 * 返回是否为开发模式
	 * 
	 * 开发模式：
	 * 
	 * 1.日志模块只输出控制台，并不写入日志文件。
	 * 2.脚本源文件夹中，支持 .disabled 文件，屏蔽指定文件夹（包括子文件夹）中的源文件。
	 *   因为有些脚本只有在生产环境中连接生产库，或调用生产环境目标接口才起作用。在本地环境会报错。
	 *   比如一些定时任务没必要在本地环境跑，即可屏蔽这些脚本。
	 * 3.在自开发程序中，可以调用类加载器中方法判断是否为开发模式，针对不同模式做处理，比如选择性日志输出等。
	 * 
	 * 只有程序员在本机开发时，将本机环境设置为开发模式。切忌在测试环境和生产环境设置为开发模式。
	 * 
	 * @return
	 * 2018年2月7日
	 * @author MBG
	 */
	@Override
    public boolean isDevelopMode() {
		return developMode;
	}
	
	
	/**
	 * 返回是否存在扩展包文件路径
	 * 
	 * 有时候，为了要支持某一个功能，要加载大量jar包，比如poi
	 * 如果都放到lib文件夹中，就显得这个文件夹中文件太多太杂，不好管理
	 * 于是就支持了可以将支持某一个功能的包，放入lib的子文件夹中
	 * 
	 * @param extLibPath 相对于 /WEB-INF/lib 的文件路径
	 *                    比如 /WEB-INF/lib/poi  则传入 poi
	 *                    比如 /WEB-INF/lib/ms/ws 则传入 ms/ws
	 * @return           true存在
	 * 2018年3月30日
	 * @author MBG
	 */
	@Override
    public boolean hasExtLib(String extLibPath) {
		if(extLibPathList==null || extLibPath==null || extLibPath.length()<1) {
			return false;
		}
		return extLibPathList.contains(extLibPath);
	}
	
	/**
	 * 返回配置文件类实例
	 * @return 配置文件类实例
	 * 2018年9月5日
	 * @author MBG
	 */
	@Override
    public XmlConfProp getConfProp() {
		return xmlConfigParse.confProp;
	}
	
	
	/**
	 * 获取日志类实例（仅供内部使用）
	 * 外部使用的话，用 FLog.getLog(bf.getLogShadow(),this) 方法获取
	 * @return 日志类实例
	 * 2018年9月13日
	 * @author MBG
	 */
	protected ILog getLog() {
		if(log==null) {
			log = xmlConfigParse.log;
			if(log==null) {
				return new SystemOutLog();
			}
		}
		return log;
	}
	
	/**
	 * 获取包资源管理服务
	 * @return 包资源管理服务类实例
	 * 2019年01月18日
	 * @author MBG
	 */
	@Override
    public synchronized ResourceService getResourceService() {
		if(rs==null) {
			if(parent!=null) {
				rs = parent.getResourceService();
			}else {
				rs = new ResourceService();
				rs.setBase(this);
			}
			try {
				setObject(ResourceService.class,rs);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		return rs;
	}
}
